﻿Imports System
Imports System.CodeDom
Imports System.Collections
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Reflection
Imports System.Text

Namespace System.Workflow.ComponentModel.Compiler
    Friend NotInheritable Class DesignTimeType
        Inherits Type
        Implements ICloneable
        ' Methods
        Friend Sub New(ByVal declaringType As Type, ByVal elementTypeFullName As String, ByVal typeProvider As ITypeProvider)
            Me.nestedTypes = New Type(0  - 1) {}
            Me.guid = Guid.Empty
            If (typeProvider Is Nothing) Then
                Throw New ArgumentNullException("typeProvider")
            End If
            If (elementTypeFullName.LastIndexOfAny(DesignTimeType.elementDecorators) = -1) Then
                Throw New ArgumentException(SR.GetString("NotElementType"), "elementTypeFullName")
            End If
            If (elementTypeFullName Is Nothing) Then
                Throw New ArgumentNullException("FullName")
            End If
            Me.fullName = Helper.EnsureTypeName(elementTypeFullName)
            Me.codeDomTypes = Nothing
            Me.nestedTypes = New Type(0  - 1) {}
            Me.codeNamespaceImports = Nothing
            Me.typeProvider = typeProvider
            Me.declaringType = declaringType
            Dim elementType As Type = Me.GetElementType
            If (elementType Is Nothing) Then
                Throw New ArgumentException(SR.GetString("NotElementType"), "elementTypeFullName")
            End If
            If MyBase.IsArray Then
                Me.typeAttributes = (((elementType.Attributes And TypeAttributes.VisibilityMask) Or TypeAttributes.Sealed) Or TypeAttributes.Serializable)
            Else
                Me.typeAttributes = TypeAttributes.AutoLayout
            End If
        End Sub

        Friend Sub New(ByVal declaringType As Type, ByVal typeName As String, ByVal codeNamespaceImports As CodeNamespaceImportCollection, ByVal namespaceName As String, ByVal typeProvider As ITypeProvider)
            Me.nestedTypes = New Type(0  - 1) {}
            Me.guid = Guid.Empty
            If (typeName Is Nothing) Then
                Throw New ArgumentNullException("typeName")
            End If
            If (codeNamespaceImports Is Nothing) Then
                Throw New ArgumentNullException("codeNamespaceImports")
            End If
            If (typeProvider Is Nothing) Then
                Throw New ArgumentNullException("typeProvider")
            End If
            If ((namespaceName Is Nothing) AndAlso (declaringType Is Nothing)) Then
                Throw New InvalidOperationException(SR.GetString("NamespaceAndDeclaringTypeCannotBeNull"))
            End If
            typeName = Helper.EnsureTypeName(typeName)
            namespaceName = Helper.EnsureTypeName(namespaceName)
            If (declaringType Is Nothing) Then
                If (namespaceName.Length = 0) Then
                    Me.fullName = typeName
                Else
                    Me.fullName = (namespaceName & "." & typeName)
                End If
            Else
                Me.fullName = (declaringType.FullName & "+" & typeName)
            End If
            Me.codeDomTypes = New List([Of] CodeTypeDeclaration)
            Me.codeNamespaceImports = codeNamespaceImports
            Me.typeProvider = typeProvider
            Me.declaringType = declaringType
            Me.typeAttributes = TypeAttributes.AutoLayout
        End Sub

        Friend Sub AddCodeTypeDeclaration(ByVal codeDomType As CodeTypeDeclaration)
            If (codeDomType Is Nothing) Then
                Throw New ArgumentNullException("codeDomType")
            End If
            Me.typeAttributes = (Me.typeAttributes Or (codeDomType.TypeAttributes And Not TypeAttributes.Public))
            Me.typeAttributes = (Me.typeAttributes Or Helper.ConvertToTypeAttributes(codeDomType.Attributes, Me.declaringType))
            Dim declaration As CodeAttributeDeclaration
            For Each declaration In codeDomType.CustomAttributes
                If ((String.Equals(declaration.Name, "System.SerializableAttribute", StringComparison.Ordinal) OrElse String.Equals(declaration.Name, "System.Serializable", StringComparison.Ordinal)) OrElse (String.Equals(declaration.Name, "SerializableAttribute", StringComparison.Ordinal) OrElse String.Equals(declaration.Name, "Serializable", StringComparison.Ordinal))) Then
                    Me.typeAttributes = (Me.typeAttributes Or TypeAttributes.Serializable)
                    Exit For
                End If
            Next
            Me.codeDomTypes.Add(codeDomType)
            Me.attributes = Nothing
            Me.constructors = Nothing
            Me.fields = Nothing
            Me.events = Nothing
            Me.properties = Nothing
            Me.methods = Nothing
            Me.LoadNestedTypes(codeDomType)
        End Sub

        Public Function Clone() As Object
            Return Me
        End Function

        Private Function CreateMemberInfo(ByVal memberInfoType As Type, ByVal member As CodeTypeMember) As MemberInfo
            Dim info As MemberInfo = Nothing
            If ((memberInfoType Is GetType(PropertyInfo)) AndAlso TypeOf member Is CodeMemberProperty) Then
                Return New DesignTimePropertyInfo(Me, [TryCast](member,CodeMemberProperty))
            End If
            If ((memberInfoType Is GetType(EventInfo)) AndAlso TypeOf member Is CodeMemberEvent) Then
                Return New DesignTimeEventInfo(Me, [TryCast](member,CodeMemberEvent))
            End If
            If ((memberInfoType Is GetType(FieldInfo)) AndAlso TypeOf member Is CodeMemberField) Then
                Return New DesignTimeFieldInfo(Me, [TryCast](member,CodeMemberField))
            End If
            If ((memberInfoType Is GetType(ConstructorInfo)) AndAlso (TypeOf member Is CodeConstructor OrElse TypeOf member Is CodeTypeConstructor)) Then
                Return New DesignTimeConstructorInfo(Me, [TryCast](member,CodeMemberMethod))
            End If
            If ((memberInfoType Is GetType(MethodInfo)) AndAlso (member.GetType Is GetType(CodeMemberMethod))) Then
                info = New DesignTimeMethodInfo(Me, [TryCast](member,CodeMemberMethod))
            End If
            Return info
        End Function

        Private Sub EnsureMembers(ByVal type As Type)
            If ((type Is GetType(PropertyInfo)) AndAlso (Me.properties Is Nothing)) Then
                Me.properties = Me.GetCodeDomMembers([Of] PropertyInfo).ToArray
            ElseIf ((type Is GetType(FieldInfo)) AndAlso (Me.fields Is Nothing)) Then
                Me.fields = Me.GetCodeDomMembers([Of] FieldInfo).ToArray
            ElseIf ((type Is GetType(ConstructorInfo)) AndAlso (Me.constructors Is Nothing)) Then
                Me.constructors = Me.GetCodeDomConstructors.ToArray
            ElseIf ((type Is GetType(EventInfo)) AndAlso (Me.events Is Nothing)) Then
                Me.events = Me.GetCodeDomMembers([Of] EventInfo).ToArray
            ElseIf ((type Is GetType(MethodInfo)) AndAlso (Me.methods Is Nothing)) Then
                Me.EnsureMembers(GetType(PropertyInfo))
                Me.EnsureMembers(GetType(EventInfo))
                Dim codeDomMembers As List([Of] MethodInfo) = Me.GetCodeDomMembers([Of] MethodInfo)
                Dim item As MethodInfo = Nothing
                Dim info2 As PropertyInfo
                For Each info2 In Me.properties
                    item = info2.GetGetMethod
                    If (Not item Is Nothing) Then
                        codeDomMembers.Add(item)
                    End If
                    item = info2.GetSetMethod
                    If (Not item Is Nothing) Then
                        codeDomMembers.Add(item)
                    End If
                Next
                Dim info3 As EventInfo
                For Each info3 In Me.events
                    item = info3.GetAddMethod
                    If (Not item Is Nothing) Then
                        codeDomMembers.Add(item)
                    End If
                    item = info3.GetRemoveMethod
                    If (Not item Is Nothing) Then
                        codeDomMembers.Add(item)
                    End If
                    item = info3.GetRaiseMethod
                    If (Not item Is Nothing) Then
                        codeDomMembers.Add(item)
                    End If
                Next
                Me.methods = codeDomMembers.ToArray
            End If
        End Sub

        Private Function FilterMember(ByVal memberInfo As MemberInfo, ByVal bindingFlags As BindingFlags) As Boolean
            Dim isPublic As Boolean = False
            Dim isStatic As Boolean = False
            If MyBase.IsInterface Then
                isPublic = True
                isStatic = False
            ElseIf TypeOf memberInfo Is MethodBase Then
                isPublic = [TryCast](memberInfo,MethodBase).IsPublic
                isStatic = [TryCast](memberInfo,MethodBase).IsStatic
            ElseIf TypeOf memberInfo Is DesignTimeEventInfo Then
                isPublic = [TryCast](memberInfo,DesignTimeEventInfo).IsPublic
                isStatic = [TryCast](memberInfo,DesignTimeEventInfo).IsStatic
            ElseIf TypeOf memberInfo Is FieldInfo Then
                isPublic = [TryCast](memberInfo,FieldInfo).IsPublic
                isStatic = [TryCast](memberInfo,FieldInfo).IsStatic
            ElseIf TypeOf memberInfo Is PropertyInfo Then
                Dim info As PropertyInfo = [TryCast](memberInfo,PropertyInfo)
                Dim getMethod As MethodInfo = Nothing
                If info.CanRead Then
                    getMethod = info.GetGetMethod(True)
                Else
                    getMethod = info.GetSetMethod(True)
                End If
                If (Not getMethod Is Nothing) Then
                    isPublic = getMethod.IsPublic
                    isStatic = getMethod.IsStatic
                End If
            ElseIf TypeOf memberInfo Is Type Then
                isPublic = ([TryCast](memberInfo,Type).IsPublic OrElse [TryCast](memberInfo,Type).IsNestedPublic)
                Return ((isPublic AndAlso ((bindingFlags And BindingFlags.Public) <> BindingFlags.Default)) OrElse (Not isPublic AndAlso ((bindingFlags And BindingFlags.NonPublic) <> BindingFlags.Default)))
            End If
            If ((Not isPublic OrElse ((bindingFlags And BindingFlags.Public) = BindingFlags.Default)) AndAlso (isPublic OrElse ((bindingFlags And BindingFlags.NonPublic) = BindingFlags.Default))) Then
                Return False
            End If
            Return ((isStatic AndAlso ((bindingFlags And BindingFlags.Static) <> BindingFlags.Default)) OrElse (Not isStatic AndAlso ((bindingFlags And BindingFlags.Instance) <> BindingFlags.Default)))
        End Function

        Public Overrides Function GetArrayRank() As Integer
            If Not MyBase.IsArray Then
                Throw New ArgumentException(TypeSystemSR.GetString("Error_TypeIsNotArray"))
            End If
            Dim num As Integer = Me.Name.LastIndexOf("["c)
            Dim num2 As Integer = 1
            Do While (Me.Name.Chars(num) <> "]"c)
                If (Me.Name.Chars(num) = ","c) Then
                    num2 += 1
                End If
                num += 1
            Loop
            Return num2
        End Function

        Protected Overrides Function GetAttributeFlagsImpl() As TypeAttributes
            Return Me.typeAttributes
        End Function

        Friend Function GetBaseMember(ByVal type As Type, ByVal baseType As Type, ByVal bindingAttr As BindingFlags, ByVal memberSignature As MemberSignature) As MemberInfo
            If (memberSignature Is Nothing) Then
                Throw New ArgumentNullException("memberSignature")
            End If
            If (baseType Is Nothing) Then
                Return Nothing
            End If
            Dim nestedType As MemberInfo = Nothing
            If GetType(PropertyInfo).IsAssignableFrom(type) Then
                If (Not memberSignature.Parameters Is Nothing) Then
                    Return baseType.GetProperty(memberSignature.Name, bindingAttr, Nothing, memberSignature.ReturnType, memberSignature.Parameters, Nothing)
                End If
                Return baseType.GetProperty(memberSignature.Name, bindingAttr)
            End If
            If GetType(EventInfo).IsAssignableFrom(type) Then
                Return baseType.GetEvent(memberSignature.Name, bindingAttr)
            End If
            If GetType(ConstructorInfo).IsAssignableFrom(type) Then
                Return baseType.GetConstructor(bindingAttr, Nothing, memberSignature.Parameters, Nothing)
            End If
            If GetType(MethodInfo).IsAssignableFrom(type) Then
                If (Not memberSignature.Parameters Is Nothing) Then
                    Return baseType.GetMethod(memberSignature.Name, bindingAttr, Nothing, memberSignature.Parameters, Nothing)
                End If
                Return baseType.GetMethod(memberSignature.Name, bindingAttr)
            End If
            If GetType(FieldInfo).IsAssignableFrom(type) Then
                Return baseType.GetField(memberSignature.Name, bindingAttr)
            End If
            If GetType(Type).IsAssignableFrom(type) Then
                nestedType = baseType.GetNestedType(memberSignature.Name, bindingAttr)
            End If
            Return nestedType
        End Function

        Private Function GetBaseMembers(ByVal type As Type, ByVal baseType As Type, ByVal bindingAttr As BindingFlags) As MemberInfo()
            Dim nestedTypes As MemberInfo() = Nothing
            If (type Is GetType(PropertyInfo)) Then
                Return baseType.GetProperties(bindingAttr)
            End If
            If (type Is GetType(EventInfo)) Then
                Return baseType.GetEvents(bindingAttr)
            End If
            If (type Is GetType(ConstructorInfo)) Then
                Return baseType.GetConstructors(bindingAttr)
            End If
            If (type Is GetType(MethodInfo)) Then
                Return baseType.GetMethods(bindingAttr)
            End If
            If (type Is GetType(FieldInfo)) Then
                Return baseType.GetFields(bindingAttr)
            End If
            If (type Is GetType(Type)) Then
                nestedTypes = baseType.GetNestedTypes(bindingAttr)
            End If
            Return nestedTypes
        End Function

        Private Function GetCodeDomConstructors() As List([Of] ConstructorInfo)
            Dim codeDomMembers As List([Of] ConstructorInfo) = Me.GetCodeDomMembers([Of] ConstructorInfo)
            If (MyBase.IsValueType OrElse ((codeDomMembers.Count = 0) AndAlso Not MyBase.IsAbstract)) Then
                Dim codeConstructor As New CodeConstructor { _
                    .Attributes = MemberAttributes.Public _
                }
                Dim item As ConstructorInfo = New DesignTimeConstructorInfo(Me, codeConstructor)
                codeDomMembers.Add(item)
            End If
            Return codeDomMembers
        End Function

        Private Function GetCodeDomMembers([Of] T As MemberInfo)() As List([Of] T)
            Dim list As New List([Of] T)
            If (Not Me.codeDomTypes Is Nothing) Then
                Dim declaration As CodeTypeDeclaration
                For Each declaration In Me.codeDomTypes
                    If (TypeOf declaration Is CodeTypeDelegate AndAlso (GetType(T) Is GetType(MethodInfo))) Then
                        Dim method As New CodeMemberMethod { _
                            .Name = "Invoke", _
                            .Attributes = MemberAttributes.Public _
                        }
                        Dim expression As CodeParameterDeclarationExpression
                        For Each expression In DirectCast(declaration, CodeTypeDelegate).Parameters
                            method.Parameters.Add(expression)
                        Next
                        method.ReturnType = DirectCast(declaration, CodeTypeDelegate).ReturnType
                        list.Add(DirectCast(Me.CreateMemberInfo(GetType(MethodInfo), method), T))
                    End If
                    Dim member As CodeTypeMember
                    For Each member In declaration.Members
                        Dim item As T = DirectCast(Me.CreateMemberInfo(GetType(T), member), T)
                        If (Not item Is Nothing) Then
                            list.Add(item)
                        End If
                    Next
                Next
            End If
            Return list
        End Function

        Protected Overrides Function GetConstructorImpl(ByVal bindingAttr As BindingFlags, ByVal binder As Binder, ByVal callConvention As CallingConventions, ByVal types As Type(), ByVal modifiers As ParameterModifier()) As ConstructorInfo
            Return Me.GetMemberHelper([Of] ConstructorInfo)(bindingAttr, New MemberSignature(Nothing, types, Nothing), (Me.constructors))
        End Function

        Public Overrides Function GetConstructors(ByVal bindingAttr As BindingFlags) As ConstructorInfo()
            Return Me.GetMembersHelper([Of] ConstructorInfo)(bindingAttr, (Me.constructors), False)
        End Function

        Public Overrides Function GetCustomAttributes(ByVal inherit As Boolean) As Object()
            Return Me.GetCustomAttributes(GetType(Object), inherit)
        End Function

        Public Overrides Function GetCustomAttributes(ByVal attributeType As Type, ByVal inherit As Boolean) As Object()
            If (attributeType Is Nothing) Then
                Throw New ArgumentNullException("attributeType")
            End If
            If ((Not Me.codeDomTypes Is Nothing) AndAlso (Me.attributes Is Nothing)) Then
                Dim codeAttributeCollection As New CodeAttributeDeclarationCollection
                Dim declaration As CodeTypeDeclaration
                For Each declaration In Me.codeDomTypes
                    codeAttributeCollection.AddRange(declaration.CustomAttributes)
                Next
                Me.attributes = Helper.LoadCustomAttributes(codeAttributeCollection, Me)
            End If
            If (Not Me.attributes Is Nothing) Then
                Return Helper.GetCustomAttributes(attributeType, inherit, Me.attributes, Me)
            End If
            Return New Object(0  - 1) {}
        End Function

        Public Overrides Function GetDefaultMembers() As MemberInfo()
            Dim attribute As DefaultMemberAttribute = Nothing
            Dim type As Type = Me
            Do While (Not type Is Nothing)
                Dim customAttributes As Object() = Me.GetCustomAttributes(GetType(DefaultMemberAttribute), False)
                If ((Not customAttributes Is Nothing) AndAlso (customAttributes.Length > 0)) Then
                    attribute = [TryCast](customAttributes(0),DefaultMemberAttribute)
                End If
                If (Not attribute Is Nothing) Then
                    Exit Do
                End If
                type = type.BaseType
            Loop
            If (attribute Is Nothing) Then
                Return New MemberInfo(0  - 1) {}
            End If
            Dim memberName As String = attribute.MemberName
            Dim member As MemberInfo() = MyBase.GetMember(memberName)
            If (member Is Nothing) Then
                member = New MemberInfo(0  - 1) {}
            End If
            Return member
        End Function

        Public Overrides Function GetElementType() As Type
            Dim type As Type = Nothing
            Dim length As Integer = Me.fullName.LastIndexOfAny(DesignTimeType.elementDecorators)
            If (length >= 0) Then
                type = Me.ResolveType(Me.fullName.Substring(0, length))
            End If
            Return type
        End Function

        Public Function GetEnumType() As Type
            If (Not Me.codeDomTypes Is Nothing) Then
                Dim declaration As CodeTypeDeclaration
                For Each declaration In Me.codeDomTypes
                    Dim type As Type = [TryCast](declaration.UserData.Item(GetType(Enum)),Type)
                    If (Not type Is Nothing) Then
                        Return type
                    End If
                    If (declaration.BaseTypes.Count > 1) Then
                        Dim reference As CodeTypeReference = declaration.BaseTypes.Item(1)
                        Dim type2 As Type = [TryCast](reference.UserData.Item(GetType(Enum)),Type)
                        If (Not type2 Is Nothing) Then
                            Return type2
                        End If
                    End If
                Next
            End If
            Return GetType(Integer)
        End Function

        Public Overrides Function GetEvent(ByVal name As String, ByVal bindingAttr As BindingFlags) As EventInfo
            Return Me.GetMemberHelper([Of] EventInfo)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.events))
        End Function

        Public Overrides Function GetEvents(ByVal bindingAttr As BindingFlags) As EventInfo()
            Return Me.GetMembersHelper([Of] EventInfo)(bindingAttr, (Me.events), True)
        End Function

        Public Overrides Function GetField(ByVal name As String, ByVal bindingAttr As BindingFlags) As FieldInfo
            Return Me.GetMemberHelper([Of] FieldInfo)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.fields))
        End Function

        Public Overrides Function GetFields(ByVal bindingAttr As BindingFlags) As FieldInfo()
            Return Me.GetMembersHelper([Of] FieldInfo)(bindingAttr, (Me.fields), True)
        End Function

        Public Overrides Function GetHashCode() As Integer
            Return MyBase.GetHashCode
        End Function

        Public Overrides Function GetInterface(ByVal name As String, ByVal ignoreCase As Boolean) As Type
            If (Not Me.codeDomTypes Is Nothing) Then
                Dim comparisonType As StringComparison = If(ignoreCase, StringComparison.OrdinalIgnoreCase, StringComparison.Ordinal)
                Dim declaration As CodeTypeDeclaration
                For Each declaration In Me.codeDomTypes
                    Dim reference As CodeTypeReference
                    For Each reference In declaration.BaseTypes
                        Dim type As Type = Me.ResolveType(DesignTimeType.GetTypeNameFromCodeTypeReference(reference, Me))
                        If (Not type Is Nothing) Then
                            If (type.IsInterface AndAlso String.Equals(type.FullName, name, comparisonType)) Then
                                Return type
                            End If
                            Dim type2 As Type = type.GetInterface(name, ignoreCase)
                            If (Not type2 Is Nothing) Then
                                Return type2
                            End If
                        End If
                    Next
                Next
            End If
            Return Nothing
        End Function

        Public Overrides Function GetInterfaces() As Type()
            Dim list As New ArrayList
            If (Not Me.codeDomTypes Is Nothing) Then
                Dim declaration As CodeTypeDeclaration
                For Each declaration In Me.codeDomTypes
                    Dim reference As CodeTypeReference
                    For Each reference In declaration.BaseTypes
                        Dim item As Type = Me.ResolveType(DesignTimeType.GetTypeNameFromCodeTypeReference(reference, Me))
                        If (Not item Is Nothing) Then
                            If (item.IsInterface AndAlso Not list.Contains(item)) Then
                                list.Add(item)
                            End If
                            Dim type2 As Type
                            For Each type2 In item.GetInterfaces
                                If ((Not type2 Is Nothing) AndAlso Not list.Contains(type2)) Then
                                    list.Add(type2)
                                End If
                            Next
                        End If
                    Next
                Next
            End If
            Return DirectCast(list.ToArray(GetType(Type)), Type())
        End Function

        Public Overrides Function GetMember(ByVal name As String, ByVal type As MemberTypes, ByVal bindingAttr As BindingFlags) As MemberInfo()
            Me.VerifyGetMemberArguments(name, bindingAttr)
            Dim list As New List([Of] MemberInfo)
            If ((type And MemberTypes.Method) <> 0) Then
                list.AddRange(Me.GetMembersHelper([Of] MethodInfo)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.methods)))
            End If
            If ((type And MemberTypes.Constructor) <> 0) Then
                list.AddRange(Me.GetMembersHelper([Of] ConstructorInfo)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.constructors)))
            End If
            If ((type And MemberTypes.Property) <> 0) Then
                list.AddRange(Me.GetMembersHelper([Of] PropertyInfo)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.properties)))
            End If
            If ((type And MemberTypes.Event) <> 0) Then
                list.AddRange(Me.GetMembersHelper([Of] EventInfo)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.events)))
            End If
            If ((type And MemberTypes.Field) <> 0) Then
                list.AddRange(Me.GetMembersHelper([Of] FieldInfo)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.fields)))
            End If
            If ((type And MemberTypes.NestedType) <> 0) Then
                list.AddRange(Me.GetMembersHelper([Of] Type)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.nestedTypes)))
            End If
            Return list.ToArray
        End Function

        Private Function GetMemberHelper([Of] T As MemberInfo)(ByVal bindingAttr As BindingFlags, ByVal memberSignature As MemberSignature, ByRef members As T()) As T
            Me.VerifyGetMemberArguments(bindingAttr)
            Me.EnsureMembers(GetType(T))
            Dim local As T
            For Each local In members
                Dim signature As New MemberSignature(local)
                If (signature.FilterSignature(memberSignature) AndAlso Me.FilterMember(local, bindingAttr)) Then
                    Return local
                End If
            Next
            If ((bindingAttr And BindingFlags.DeclaredOnly) = BindingFlags.Default) Then
                If ((bindingAttr And BindingFlags.FlattenHierarchy) = BindingFlags.Default) Then
                    bindingAttr = (bindingAttr And Not BindingFlags.Static)
                End If
                Dim baseType As Type = Me.BaseType
                If (Not baseType Is Nothing) Then
                    Dim local2 As T = DirectCast(Me.GetBaseMember(GetType(T), baseType, bindingAttr, memberSignature), T)
                    If (Not local2 Is Nothing) Then
                        If (((Not TypeOf local2 Is FieldInfo OrElse Not [TryCast](local2,FieldInfo).IsPrivate) AndAlso (Not TypeOf local2 Is MethodBase OrElse Not [TryCast](local2,MethodBase).IsPrivate)) AndAlso (Not TypeOf local2 Is Type OrElse Not [TryCast](local2,Type).IsNestedPrivate)) Then
                            Return local2
                        End If
                        Return CType(Nothing, T)
                    End If
                End If
            End If
            Return CType(Nothing, T)
        End Function

        Public Overrides Function GetMembers(ByVal bindingAttr As BindingFlags) As MemberInfo()
            Me.VerifyGetMemberArguments(bindingAttr)
            Dim list As New ArrayList
            list.AddRange(Me.GetMethods(bindingAttr))
            list.AddRange(Me.GetProperties(bindingAttr))
            list.AddRange(Me.GetEvents(bindingAttr))
            list.AddRange(Me.GetFields(bindingAttr))
            list.AddRange(Me.GetNestedTypes(bindingAttr))
            Return DirectCast(list.ToArray(GetType(MemberInfo)), MemberInfo())
        End Function

        Private Function GetMembersHelper([Of] T As MemberInfo)(ByVal bindingAttr As BindingFlags, ByVal memberSignature As MemberSignature, ByRef members As T()) As T()
            Dim list As New List([Of] T)
            Dim local As T
            For Each local In Me.GetMembersHelper([Of] T)(bindingAttr, (members), True)
                Dim signature As New MemberSignature(local)
                If signature.FilterSignature(memberSignature) Then
                    list.Add(local)
                End If
            Next
            Return list.ToArray
        End Function

        Private Function GetMembersHelper([Of] T As MemberInfo)(ByVal bindingAttr As BindingFlags, ByRef members As T(), ByVal searchBase As Boolean) As T()
            Me.VerifyGetMemberArguments(bindingAttr)
            Me.EnsureMembers(GetType(T))
            Dim dictionary As New Dictionary([Of] MemberSignature, T)
            Dim local As T
            For Each local In members
                Dim key As New MemberSignature(local)
                If (Me.FilterMember(local, bindingAttr) AndAlso Not dictionary.ContainsKey(key)) Then
                    dictionary.Add(New MemberSignature(local), local)
                End If
            Next
            If (searchBase AndAlso ((bindingAttr And BindingFlags.DeclaredOnly) = BindingFlags.Default)) Then
                If ((bindingAttr And BindingFlags.FlattenHierarchy) = BindingFlags.Default) Then
                    bindingAttr = (bindingAttr And Not BindingFlags.Static)
                End If
                Dim baseType As Type = Me.BaseType
                If (Not baseType Is Nothing) Then
                    Dim localArray As T() = [TryCast](Me.GetBaseMembers(GetType(T), baseType, bindingAttr),T())
                    Dim local2 As T
                    For Each local2 In localArray
                        If (((Not TypeOf local2 Is FieldInfo OrElse Not [TryCast](local2,FieldInfo).IsPrivate) AndAlso (Not TypeOf local2 Is MethodBase OrElse Not [TryCast](local2,MethodBase).IsPrivate)) AndAlso (Not TypeOf local2 Is Type OrElse Not [TryCast](local2,Type).IsNestedPrivate)) Then
                            Dim signature2 As New MemberSignature(local2)
                            If Not dictionary.ContainsKey(signature2) Then
                                dictionary.Add(signature2, local2)
                            End If
                        End If
                    Next
                End If
            End If
            Dim list As New List([Of] T)(dictionary.Values)
            Return list.ToArray
        End Function

        Protected Overrides Function GetMethodImpl(ByVal name As String, ByVal bindingAttr As BindingFlags, ByVal binder As Binder, ByVal callConvention As CallingConventions, ByVal types As Type(), ByVal modifiers As ParameterModifier()) As MethodInfo
            Return Me.GetMemberHelper([Of] MethodInfo)(bindingAttr, New MemberSignature(name, types, Nothing), (Me.methods))
        End Function

        Public Overrides Function GetMethods(ByVal bindingAttr As BindingFlags) As MethodInfo()
            Return Me.GetMembersHelper([Of] MethodInfo)(bindingAttr, (Me.methods), True)
        End Function

        Public Overrides Function GetNestedType(ByVal name As String, ByVal bindingAttr As BindingFlags) As Type
            Return Me.GetMemberHelper([Of] Type)(bindingAttr, New MemberSignature(name, Nothing, Nothing), (Me.nestedTypes))
        End Function

        Public Overrides Function GetNestedTypes(ByVal bindingAttr As BindingFlags) As Type()
            Return Me.GetMembersHelper([Of] Type)(bindingAttr, (Me.nestedTypes), False)
        End Function

        Public Overrides Function GetProperties(ByVal bindingAttr As BindingFlags) As PropertyInfo()
            Return Me.GetMembersHelper([Of] PropertyInfo)(bindingAttr, (Me.properties), True)
        End Function

        Protected Overrides Function GetPropertyImpl(ByVal name As String, ByVal bindingAttr As BindingFlags, ByVal binder As Binder, ByVal returnType As Type, ByVal types As Type(), ByVal modifiers As ParameterModifier()) As PropertyInfo
            Return Me.GetMemberHelper([Of] PropertyInfo)(bindingAttr, New MemberSignature(name, types, Nothing), (Me.properties))
        End Function

        Friend Shared Function GetTypeNameFromCodeTypeReference(ByVal codeTypeReference As CodeTypeReference, ByVal declaringType As DesignTimeType) As String
            Dim builder As New StringBuilder
            If (codeTypeReference.ArrayRank = 0) Then
                Dim type As Type = Nothing
                If (Not declaringType Is Nothing) Then
                    type = declaringType.ResolveType(codeTypeReference.BaseType)
                End If
                If (Not type Is Nothing) Then
                    builder.Append(type.FullName)
                Else
                    builder.Append(codeTypeReference.BaseType)
                End If
                If ((Not codeTypeReference.TypeArguments Is Nothing) AndAlso (codeTypeReference.TypeArguments.Count > 0)) Then
                    If (codeTypeReference.BaseType.IndexOf("`"c) = -1) Then
                        builder.Append(String.Format(CultureInfo.InvariantCulture, "`{0}", New Object() { codeTypeReference.TypeArguments.Count }))
                    End If
                    builder.Append("[")
                    Dim reference As CodeTypeReference
                    For Each reference In codeTypeReference.TypeArguments
                        builder.Append("[")
                        builder.Append(DesignTimeType.GetTypeNameFromCodeTypeReference(reference, declaringType))
                        builder.Append("],")
                    Next
                    builder.Length -= 1
                    builder.Append("]")
                End If
            Else
                builder.Append(DesignTimeType.GetTypeNameFromCodeTypeReference(codeTypeReference.ArrayElementType, declaringType))
                builder.Append("[")
                Dim i As Integer
                For i = 0 To (codeTypeReference.ArrayRank - 1) - 1
                    builder.Append(","c)
                Next i
                builder.Append("]")
            End If
            Return builder.ToString
        End Function

        Protected Overrides Function HasElementTypeImpl() As Boolean
            Return (Me.Name.LastIndexOfAny(DesignTimeType.elementDecorators) <> -1)
        End Function

        Public Overrides Function InvokeMember(ByVal name As String, ByVal bindingFlags As BindingFlags, ByVal binder As Binder, ByVal target As Object, ByVal providedArgs As Object(), ByVal modifiers As ParameterModifier(), ByVal culture As CultureInfo, ByVal namedParams As String()) As Object
            Throw New NotImplementedException(TypeSystemSR.GetString("Error_RuntimeNotSupported"))
        End Function

        Protected Overrides Function IsArrayImpl() As Boolean
            Dim num As Integer = Me.Name.LastIndexOfAny(DesignTimeType.elementDecorators)
            Return ((num <> -1) AndAlso (Me.Name.Chars(num) = "["c))
        End Function

        Public Overrides Function IsAssignableFrom(ByVal c As Type) As Boolean
            Return TypeProvider.IsAssignable(Me, c)
        End Function

        Protected Overrides Function IsByRefImpl() As Boolean
            Return (Me.fullName.Chars((Me.fullName.Length - 1)) = "&"c)
        End Function

        Protected Overrides Function IsCOMObjectImpl() As Boolean
            Return False
        End Function

        Protected Overrides Function IsContextfulImpl() As Boolean
            Return False
        End Function

        Public Overrides Function IsDefined(ByVal attributeType As Type, ByVal inherit As Boolean) As Boolean
            If (attributeType Is Nothing) Then
                Throw New ArgumentNullException("attributeType")
            End If
            Me.GetCustomAttributes(True)
            Return Helper.IsDefined(attributeType, inherit, Me.attributes, Me)
        End Function

        Protected Overrides Function IsMarshalByRefImpl() As Boolean
            Return False
        End Function

        Protected Overrides Function IsPointerImpl() As Boolean
            Return (Me.fullName.Chars((Me.fullName.Length - 1)) = "*"c)
        End Function

        Protected Overrides Function IsPrimitiveImpl() As Boolean
            Return False
        End Function

        Public Overrides Function IsSubclassOf(ByVal c As Type) As Boolean
            If (c Is Nothing) Then
                Return False
            End If
            Return TypeProvider.IsSubclassOf(Me, c)
        End Function

        Private Sub LoadNestedTypes(ByVal codeDomType As CodeTypeDeclaration)
            Dim list As New List([Of] Type)
            Dim type As Type
            For Each type In Me.nestedTypes
                list.Add(type)
            Next
            Dim member As CodeTypeMember
            For Each member In codeDomType.Members
                If Not TypeOf member Is CodeTypeDeclaration Then
                    [Continue] For
                End If
                Dim declaration As CodeTypeDeclaration = [TryCast](member,CodeTypeDeclaration)
                Dim item As Type = Nothing
                Dim type3 As Type
                For Each type3 In list
                    If type3.Name.Equals(Helper.EnsureTypeName(declaration.Name)) Then
                        item = type3
                        Exit For
                    End If
                Next
                If (item Is Nothing) Then
                    item = New DesignTimeType(Me, declaration.Name, Me.codeNamespaceImports, Me.fullName, Me.typeProvider)
                    list.Add(item)
                    DirectCast(Me.typeProvider, TypeProvider).AddType(item)
                End If
                DirectCast(item, DesignTimeType).AddCodeTypeDeclaration(declaration)
            Next
            Me.nestedTypes = list.ToArray
        End Sub

        Public Overrides Function MakeArrayType() As Type
            Return Me.typeProvider.GetType(String.Format(CultureInfo.InvariantCulture, "{0}[]", New Object() { Me.FullName }))
        End Function

        Public Overrides Function MakeByRefType() As Type
            Return Me.ResolveType((Me.fullName & "&"))
        End Function

        Friend Function ResolveType(ByVal name As String) As Type
            Dim type As Type = Nothing
            type = Me.typeProvider.GetType(name)
            If ((type Is Nothing) AndAlso Not String.IsNullOrEmpty(Me.Namespace)) Then
                type = Me.typeProvider.GetType((Me.Namespace & "." & name))
            End If
            If (type Is Nothing) Then
                type = Me.typeProvider.GetType((Me.fullName & "+" & name))
            End If
            If ((type Is Nothing) AndAlso (Not Me.codeNamespaceImports Is Nothing)) Then
                Dim import As CodeNamespaceImport
                For Each import In Me.codeNamespaceImports
                    type = Me.typeProvider.GetType((import.Namespace & "." & name))
                    If (Not type Is Nothing) Then
                        Exit For
                    End If
                Next
            End If
            If (type Is Nothing) Then
                Dim str As String = name
                Dim index As Integer = name.IndexOf("."c)
                Dim length As Integer = -1
                Do While ((length = str.LastIndexOf("."c) <> index) AndAlso (type Is Nothing))
                    str = (str.Substring(0, length) & "+" & str.Substring((length + 1)))
                    type = Me.typeProvider.GetType(str)
                Loop
            End If
            Return type
        End Function

        Public Overrides Function ToString() As String
            Return Me.fullName
        End Function

        Private Sub VerifyGetMemberArguments(ByVal bindingAttr As BindingFlags)
            Dim flags As BindingFlags = (BindingFlags.FlattenHierarchy Or (BindingFlags.NonPublic Or (BindingFlags.Public Or (BindingFlags.Static Or (BindingFlags.Instance Or (BindingFlags.DeclaredOnly Or BindingFlags.IgnoreCase))))))
            If ((bindingAttr And Not flags) <> BindingFlags.Default) Then
                Throw New ArgumentException(TypeSystemSR.GetString("Error_GetMemberBindingOptions"))
            End If
        End Sub

        Private Sub VerifyGetMemberArguments(ByVal name As String, ByVal bindingAttr As BindingFlags)
            If (name Is Nothing) Then
                Throw New ArgumentNullException("name")
            End If
            Me.VerifyGetMemberArguments(bindingAttr)
        End Sub


        ' Properties
        Public Overrides ReadOnly Property [Assembly] As Assembly
            Get
                Return Nothing
            End Get
        End Property

        Public Overrides ReadOnly Property AssemblyQualifiedName As String
            Get
                Return Me.FullName
            End Get
        End Property

        Public Overrides ReadOnly Property BaseType As Type
            Get
                Dim type As Type = Nothing
                If (Not Me.codeDomTypes Is Nothing) Then
                    Dim declaration As CodeTypeDeclaration
                    For Each declaration In Me.codeDomTypes
                        Dim reference As CodeTypeReference
                        For Each reference In declaration.BaseTypes
                            Dim type2 As Type = Me.ResolveType(DesignTimeType.GetTypeNameFromCodeTypeReference(reference, Me))
                            If ((Not type2 Is Nothing) AndAlso Not type2.IsInterface) Then
                                type = type2
                                Exit For
                            End If
                        Next
                        If ((Not type Is Nothing) AndAlso Not type.Equals(Me.ResolveType("System.Object"))) Then
                            Exit For
                        End If
                    Next
                End If
                If (type Is Nothing) Then
                    If MyBase.IsArray Then
                        Return Me.ResolveType("System.Array")
                    End If
                    If ((Me.codeDomTypes Is Nothing) OrElse (Me.codeDomTypes.Count <= 0)) Then
                        Return type
                    End If
                    If Me.codeDomTypes.Item(0).IsStruct Then
                        Return Me.ResolveType("System.ValueType")
                    End If
                    If Me.codeDomTypes.Item(0).IsEnum Then
                        Return Me.ResolveType("System.Enum")
                    End If
                    If ((Me.codeDomTypes.Item(0).IsClass AndAlso Not MyBase.IsByRef) AndAlso Not MyBase.IsPointer) Then
                        Return Me.ResolveType("System.Object")
                    End If
                    If TypeOf Me.codeDomTypes.Item(0) Is CodeTypeDelegate Then
                        type = Me.ResolveType("System.Delegate")
                    End If
                End If
                Return type
            End Get
        End Property

        Public Overrides ReadOnly Property DeclaringType As Type
            Get
                Return Me.declaringType
            End Get
        End Property

        Public Overrides ReadOnly Property FullName As String
            Get
                Return Me.fullName
            End Get
        End Property

        Public Overrides ReadOnly Property GUID As Guid
            Get
                If (Me.guid = Guid.Empty) Then
                    Me.guid = Guid.NewGuid
                End If
                Return Me.guid
            End Get
        End Property

        Public Overrides ReadOnly Property [Module] As Module
            Get
                Return Nothing
            End Get
        End Property

        Public Overrides ReadOnly Property Name As String
            Get
                Dim fullName As String = Me.fullName
                Dim index As Integer = fullName.IndexOf("["c)
                If (index <> -1) Then
                    index = fullName.Substring(0, index).LastIndexOfAny(DesignTimeType.nameSeparators)
                Else
                    index = fullName.LastIndexOfAny(DesignTimeType.nameSeparators)
                End If
                If (index <> -1) Then
                    fullName = Me.fullName.Substring((index + 1))
                End If
                Return fullName
            End Get
        End Property

        Public Overrides ReadOnly Property [Namespace] As String
            Get
                If (Me.fullName = Me.Name) Then
                    Return String.Empty
                End If
                Return Me.fullName.Substring(0, ((Me.fullName.Length - Me.Name.Length) - 1))
            End Get
        End Property

        Friend ReadOnly Property Provider As ITypeProvider
            Get
                Return Me.typeProvider
            End Get
        End Property

        Public Overrides ReadOnly Property TypeHandle As RuntimeTypeHandle
            Get
                Throw New NotImplementedException(TypeSystemSR.GetString("Error_RuntimeNotSupported"))
            End Get
        End Property

        Public Overrides ReadOnly Property UnderlyingSystemType As Type
            Get
                Return Me
            End Get
        End Property


        ' Fields
        Private attributes As Attribute()
        Private codeDomTypes As List([Of] CodeTypeDeclaration)
        Private codeNamespaceImports As CodeNamespaceImportCollection
        Private constructors As ConstructorInfo()
        Private declaringType As Type
        Private Shared ReadOnly elementDecorators As Char() = New Char() { "["c, "*"c, "&"c }
        Private events As EventInfo()
        Private fields As FieldInfo()
        Private fullName As String
        Private guid As Guid
        Private methods As MethodInfo()
        Private Shared ReadOnly nameSeparators As Char() = New Char() { "."c, "+"c }
        Private nestedTypes As Type()
        Private properties As PropertyInfo()
        Private typeAttributes As TypeAttributes
        Private typeProvider As ITypeProvider

        ' Nested Types
        Friend Class MemberSignature
            ' Methods
            Friend Sub New(ByVal memberInfo As MemberInfo)
                Me.name = memberInfo.Name
                If TypeOf memberInfo Is MethodBase Then
                    Dim list As New List([Of] Type)
                    Dim info As ParameterInfo
                    For Each info In [TryCast](memberInfo,MethodBase).GetParameters
                        list.Add(info.ParameterType)
                    Next
                    Me.parameters = list.ToArray
                    If TypeOf memberInfo Is MethodInfo Then
                        Me.returnType = DirectCast(memberInfo, MethodInfo).ReturnType
                    End If
                ElseIf TypeOf memberInfo Is PropertyInfo Then
                    Dim info2 As PropertyInfo = [TryCast](memberInfo,PropertyInfo)
                    Dim list2 As New List([Of] Type)
                    Dim info3 As ParameterInfo
                    For Each info3 In info2.GetIndexParameters
                        list2.Add(info3.ParameterType)
                    Next
                    Me.parameters = list2.ToArray
                    Me.returnType = info2.PropertyType
                End If
            End Sub

            Friend Sub New(ByVal name As String, ByVal parameters As Type(), ByVal returnType As Type)
                Me.name = name
                Me.returnType = returnType
                If (Not parameters Is Nothing) Then
                    Me.parameters = DirectCast(parameters.Clone, Type())
                End If
            End Sub

            Public Overrides Function Equals(ByVal obj As Object) As Boolean
                Dim signature As MemberSignature = [TryCast](obj,MemberSignature)
                If (((signature Is Nothing) OrElse (Me.name <> signature.name)) OrElse (Not Me.returnType Is signature.returnType)) Then
                    Return False
                End If
                If (((Me.Parameters Is Nothing) AndAlso (Not signature.Parameters Is Nothing)) OrElse ((Not Me.Parameters Is Nothing) AndAlso (signature.Parameters Is Nothing))) Then
                    Return False
                End If
                If (Not Me.Parameters Is Nothing) Then
                    If (Me.parameters.Length <> signature.parameters.Length) Then
                        Return False
                    End If
                    Dim i As Integer
                    For i = 0 To Me.parameters.Length - 1
                        If (Not Me.parameters(i) Is signature.parameters(i)) Then
                            Return False
                        End If
                    Next i
                End If
                Return True
            End Function

            Public Function FilterSignature(ByVal maskSignature As MemberSignature) As Boolean
                If (maskSignature Is Nothing) Then
                    Throw New ArgumentNullException("maskSignature")
                End If
                If (((Not maskSignature.Name Is Nothing) AndAlso (Me.name <> maskSignature.name)) OrElse ((Not maskSignature.returnType Is Nothing) AndAlso (Not Me.returnType Is maskSignature.returnType))) Then
                    Return False
                End If
                If (Not maskSignature.parameters Is Nothing) Then
                    If (Me.parameters Is Nothing) Then
                        Return False
                    End If
                    If (Me.parameters.Length <> maskSignature.parameters.Length) Then
                        Return False
                    End If
                    Dim i As Integer
                    For i = 0 To Me.parameters.Length - 1
                        If Not Me.parameters(i).Equals(maskSignature.parameters(i)) Then
                            Return False
                        End If
                    Next i
                End If
                Return True
            End Function

            Public Overrides Function GetHashCode() As Integer
                Return Me.ToString.GetHashCode
            End Function

            Public Overrides Function ToString() As String
                Dim str As String = String.Empty
                If (Not Me.returnType Is Nothing) Then
                    str = (Me.returnType.FullName & " ")
                End If
                If ((Not Me.name Is Nothing) AndAlso (Me.name.Length <> 0)) Then
                    str = (str & Me.name)
                End If
                If ((Me.parameters Is Nothing) OrElse (Me.parameters.Length <= 0)) Then
                    Return str
                End If
                str = (str & "(")
                Dim i As Integer
                For i = 0 To Me.parameters.Length - 1
                    If (i > 0) Then
                        str = (str & ", ")
                    End If
                    If (Not Me.parameters(i) Is Nothing) Then
                        If ((Not Me.parameters(i).GetType Is Nothing) AndAlso Me.parameters(i).GetType.IsByRef) Then
                            str = (str & "ref ")
                        End If
                        str = (str & Me.parameters(i).FullName)
                    End If
                Next i
                Return (str & ")")
            End Function


            ' Properties
            Public ReadOnly Property Name As String
                Get
                    Return Me.name
                End Get
            End Property

            Public ReadOnly Property Parameters As Type()
                Get
                    If (Me.parameters Is Nothing) Then
                        Return Nothing
                    End If
                    Return DirectCast(Me.parameters.Clone, Type())
                End Get
            End Property

            Public ReadOnly Property ReturnType As Type
                Get
                    Return Me.returnType
                End Get
            End Property


            ' Fields
            Private name As String
            Private parameters As Type()
            Private returnType As Type
        End Class
    End Class
End Namespace

